package edu.uow.devdocs

import org.apache.commons.collections.ListUtils
import org.springframework.dao.DataIntegrityViolationException
import grails.converters.*
import java.text.SimpleDateFormat
import java.util.Date;

class TimeTrackerController {
	
	def currentUserService
	def springSecurityService
	
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd")

	static scaffold = true
	
	def index() {
		calendar()
	}
	
	def calendar = {
		def tList = new TimeTrackerArrayCommand('dateOfWork':new Date(), 'person':currentUserService.currentUser)
		render(view: "timeTrackerCalendar", model:[timeTrackerList: tList.timeTrackers, 
			projectList: Project.allProjectsForPerson(currentUserService.currentUserId).list(),
			phaseList: Phase.list(),
			personId: currentUserService.currentUser.id])
	}

	def getEvents = {
		Date start = new Date(params.long('start') * 1000)
		Date end = new Date(params.long('end') * 1000)
		println "${start} ${end}"
		def results = TimeTracker.executeQuery("select t.person.id, t.dateOfWork, sum(t.hours) from TimeTracker t where t.dateOfWork >= ? and t.dateOfWork <= ? and t.person =? group by t.person.id,t.dateOfWork",[start,end,currentUserService.currentUser])

		render results.collect() {
			[
				id: it[1].getTime(),
				title: "" + it[2],
				start: sdf.format(it[1]),
				url: g.createLink(action:'showTime',params:['date':it[1].getTime(),'person_id':it[0]]),
				data: ['userid':it[0]]
			]
		} as JSON
	}
	
	def showTime(Long date, Integer person_id, String _action, int delta) {

		def dt = new Date(date)
		println currentUserService.currentUser
		def Person timeTrackerPerson = null
		if (person_id==null) {
			timeTrackerPerson = currentUserService.currentUser
		} else {
			timeTrackerPerson = Person.get(person_id)
		}
		println timeTrackerPerson
		def timeTrackerList = TimeTracker.findAllByDateOfWorkAndPerson(dt, timeTrackerPerson)
		println timeTrackerList
		if(_action) {
			dt = dt + delta
			if (_action=='move') {
				timeTrackerList.each{
					it.dateOfWork = dt
					it.save(flush:true)
				}
			}
			if (_action=='copy') {
				timeTrackerList.each{
					def tmp = new TimeTracker()
					tmp.properties = it.properties
					tmp.dateOfWork = dt
					tmp.save(flush:true)
				}			
			}
			timeTrackerList = TimeTracker.findAllByDateOfWorkAndPerson(dt, timeTrackerPerson)
		}
		println timeTrackerList
		def tList = new TimeTrackerArrayCommand(dateOfWork:dt,person:timeTrackerPerson)
		int x = 0
		timeTrackerList.each() {
			tList.timeTrackers[x++] = it
		}
		//def tmp = tList.timeTrackers.findAll {
		//	it.id != null
		//}
		render(view: "timeTrackerCalendar", model:[timeTrackerList: tList.timeTrackers, 
			projectList: Project.allProjectsForPerson(currentUserService.currentUserId).list(),
			phaseList: Phase.list(),
			personId: currentUserService.currentUser.id])
	}
	
	def list() {
		render(view:"list")
	}
	
	def deleteFromCalendar(int id) {
		def t = TimeTracker.get(id)
		t.delete()
		flash.message="1 deleted"
		redirect(action:'showTime', params:[date:params.long('date'), username: params.username])
	}
	
	def updateTimeTrackerList(TimeTrackerArrayCommand tList) {
		println params
		def updated = 0
		def inserted = 0
		int x = 0
		tList.timeTrackers.each() {
			if (it?.hours> 0 && !it.hasErrors()) {
				def timeTracker
				timeTracker = it?.id ? timeTracker = TimeTracker.get(it.id) : new TimeTracker()
				timeTracker.properties = it.properties
				if (!timeTracker.person) {
					timeTracker.person = currentUserService.currentUser
				}
				if (timeTracker.validate()) {
					timeTracker.id ? updated++ : inserted++
					timeTracker.save(flush:true)
					tList.timeTrackers[x] = new TimeTracker()
				} 
			}
			x++
		}
		flash.message="${inserted} inserted, ${updated} updated"
		render(view: "timeTrackerCalendar", model:[timeTrackerList: tList.timeTrackers, 
			projectList: Project.allProjectsForPerson(currentUserService.currentUserId).list(),
			phaseList: Phase.list(),
			personId: currentUserService.currentUser.id])
	}
	
	def search(Long person, Long system, Long project, Long projectType, Long phase, Long issue, Long developmentTask, Long developmentChecklist, Long team, String flagBillable, String dateFrom, String dateTo) {
		
		def dtFrom = params.date('dateFrom')
		def dtTo= params.date('dateTo')

		def query = {
			if (person) {
				eq("person", Person.get(person))
			}
			if (system) {
				def list = Project.findAllBySystem(System.get(system))
				if (list) {
					'in'("project",list)
				}
			}
			if (project) {
				eq("project", Project.get(project))
			}
			if (projectType) {
				def list = Project.findAllByProjectType( ProjectType.get(projectType))
				if (list) {
					'in'("project", list)
				}
			}
			if (phase) {
				eq("phase", Phase.get(phase))
			}
			if (issue) {
				eq("issue", Issue.get(issue))
			}
			if (developmentTask) {
				eq("developmentTask", DevelopmentTask.get(developmentTask))
			}
			if (developmentChecklist) {
				eq("developmentChecklist", DevelopmentChecklist.get(developmentChecklist))
			}
			if (team) {
				'in'("person", Person.findAllByTeam(Team.get(team)))
			}
			if (flagBillable) {
				def list = Project.findAllByFlagBillable(flagBillable)
				if (list) {
					'in'("project", list)
				}
			}
			if (dtFrom) {
				ge("dateOfWork", dtFrom)
			}
			if (dtTo) {
				le("dateOfWork", dtTo)
			}
			
			//cache(true)


		}
		def totalHrsQuery = {
			projections {
				sum("hours")
			} 
			and query
		}
		def groupByProjectQuery = {
			projections {
				groupProperty("project")
				sum("hours")
			}
			and query
		}
		def groupByPhaseQuery = {
			projections {
				groupProperty("phase")
				sum("hours")
			}
			and query
		}
		def groupByPersonQuery = {
			projections {
				groupProperty("person")
				sum("hours")
			}
			and query
		}
		def timeTrackerDetails = {
			query 
		}
		
		
		
		def totalHrs = TimeTracker.createCriteria().get(totalHrsQuery)
		def results = TimeTracker.createCriteria().list(query).sort{-1 * it.dateOfWork.time}
		def grpByProject = TimeTracker.createCriteria().list(groupByProjectQuery)
		def grpByPhase = TimeTracker.createCriteria().list(groupByPhaseQuery)
		def grpByPerson = TimeTracker.createCriteria().list(groupByPersonQuery)  
		render(view:"list",model:['timeTrackerInstanceList':results,'totalHours':totalHrs, 'grpByProject':grpByProject,'grpByPhase':grpByPhase, 'grpByPerson': grpByPerson])

	}
	
	def addTimeTrackerEvent() {
		def timeTrackerInstance = new TimeTracker()
		println params
		println currentUserService.getCurrentUser()
		bindData(timeTrackerInstance, params)
		if (!timeTrackerInstance.person) {
			timeTrackerInstance.person = currentUserService.currentUser
		}
		if (timeTrackerInstance.validate()) {
			if (timeTrackerInstance.developmentChecklist) {
				timeTrackerInstance.developmentTask=timeTrackerInstance.developmentChecklist?.developmentTask
			}
			if (timeTrackerInstance.developmentTask) {
				timeTrackerInstance.issue=timeTrackerInstance.developmentTask?.issue
			}
			timeTrackerInstance.save(flush:true)
			flash.message = message(code: 'default.created.message', args: [message(code: 'TimeTracker.label', default: 'TimeTracker'), timeTrackerInstance.id])
		}
		render(template:"/shared/addTimeTracker", model:['projectId':timeTrackerInstance?.project?.id,
			'timeTrackerInstance':timeTrackerInstance.hasErrors()?timeTrackerInstance:new TimeTracker(), 
			'issueId':timeTrackerInstance?.issue?.id,
			'developmentChecklistId':timeTrackerInstance?.developmentChecklist?.id,
			'developmentTaskId': timeTrackerInstance?.developmentTask?.id,
			'deploymentId': timeTrackerInstance?.deployment?.id])
	}
}


class TimeTrackerArrayCommand {
	def dateOfWork
	def person
	List<TimeTrackerCommand> timeTrackers
	
	List<TimeTrackerCommand> getTimeTrackers() {
		if (timeTrackers==null) {
			timeTrackers = [
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person),
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person),
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person),
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person),
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person),
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person),
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person),
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person),
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person),
				new TimeTrackerCommand(dateOfWork:dateOfWork,person:person)
				]
		}
		return timeTrackers
	}
	
 
	
	public void print() {
		timeTrackers.each{println it;}
	}
}

class TimeTrackerCommand {
	java.math.BigDecimal id
	Date dateOfWork = new Date()
	java.math.BigDecimal hours
	Date lastUpdated
	String comments
	// Relation
	Project project
	// Relation
	Phase phase
	// Relation
	Person person
	// Relation
	Issue issue
	// Relation
	DowntimeReport downtimeReport
	// Relation
	DevelopmentTask developmentTask
	DevelopmentChecklist developmentChecklist
	// Relation
	Deployment deployment
	java.math.BigDecimal taskId
	
	static constraints = {
		importFrom TimeTracker
	}
}
